package com.sys.shiro;

import java.util.*;

import com.sys.service.SysRoleService;
import com.bhudy.base.QueryFilter;
import com.sys.entity.*;
import com.bhudy.exception.SysException;
import com.sys.service.SysUserService;
import com.sys.utils.Utils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @Author com.bhudy
 * @Description 继承AuthorizingRealm，重写认证和授权方法
 * @Date 2019-10-30 23:09:37
 */
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysRoleService sysRoleService;
    private QueryFilter queryFilter = new QueryFilter();
    @Autowired
    private RetryLimitHashedCredentialsMatcher retryLimitHashedCredentialsMatcher;

    /**
     * 授权方法，如果不设置缓存管理的话，需要访问需要一定的权限或角色的请求时会进入这个方法
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SysUser sysUser = (SysUser) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        Set<String> roleSet = new HashSet<>();
        Set<Long> roleIdSet = new HashSet<>();
        Set<String> permiSet = new HashSet<>();


        QueryFilter queryFilter = new QueryFilter();
        queryFilter.and("userId", sysUser.getUserId());
        List<SysUserRole> sysUserRoleList = sysUserService.findList(SysUserRole.class, queryFilter);

        List<SysRole> sysRoleList = sysRoleService.findAll();
        Map<Long, SysRole> sysRoleMapping = new HashMap<>();
        for (SysRole sysRole : sysRoleList) {
            sysRoleMapping.put(sysRole.getRoleId(), sysRole);
        }
        if (sysUserRoleList != null && sysUserRoleList.size() != 0) {
            for (SysUserRole userRole : sysUserRoleList) {
                SysRole sysRole = sysRoleMapping.get(userRole.getRoleId());
                roleSet.add(sysRole.getRoleSign());
                roleIdSet.add(userRole.getRoleId());
            }
        }

        String sql = "select " + sysUserService.keywords("get", "post", "put", "delete", "url") + " from sys_role_menu brm inner join sys_menu bm on brm.menu_id = bm.id where " + sysUserService.keyword("url") + " != '' and " + sysUserService.keyword("url") + " is not null and brm.role_id in ?";
        List<Map<String, Object>> sysMenuMapList = sysUserService.findMapList(sql, roleIdSet);

        if (sysMenuMapList != null && sysMenuMapList.size() != 0) {
            for (Map<String, Object> dataMap : sysMenuMapList) {
                String url = dataMap.get("url").toString();
                String get = dataMap.get("get").toString();
                String post = dataMap.get("post").toString();
                String put = dataMap.get("put").toString();
                String delete = dataMap.get("delete").toString();
                if (get.equals("1")) permiSet.add("get:" + url);
                if (post.equals("1")) permiSet.add("post:" + url);
                if (put.equals("1")) permiSet.add("put:" + url);
                if (delete.equals("1")) permiSet.add("delete:" + url);
            }
        }

        authorizationInfo.setRoles(roleSet);
        authorizationInfo.setStringPermissions(permiSet);

        return authorizationInfo;
    }

    /**
     * 认证方法
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        //根据登录名查询用户，这里不用校验密码，因为密码的校验是交给shiro来完成的
        QueryFilter queryFilter = new QueryFilter();
        queryFilter.and("loginCode", userToken.getUsername());
        queryFilter.limit(0, 1);
        SysUser sysUser = sysUserService.find(queryFilter);

        if (userToken.getUsername() == null || userToken.getUsername().equals("")) {
            throw new UnknownAccountException();
        }
        if (userToken.getPassword() == null || userToken.getPassword().equals("")) {
            throw new UnknownAccountException();
        }
        if (sysUser == null) {
            throw new IncorrectCredentialsException();
        }
        if (sysUser.getStatus() != 0) {
            throw new LockedAccountException();
        }

        sysUser.setLastLoginDate(new Date());
        sysUser.setLastLoginIp(Utils.getRequestIp());

        sysUserService.update(sysUser);
        return new SimpleAuthenticationInfo(sysUser, sysUser.getPassword(), ByteSource.Util.bytes(sysUser.getSalt()), getName());

       /* String password = String.valueOf(userToken.getPassword());

        if (password.equals(sysUser.getPassword())) {
            return new SimpleAuthenticationInfo(sysUser, password, getName());
        } else {
            if (Utils.md5(password, sysUser.getSalt()).equals(sysUser.getPassword())){
                return new SimpleAuthenticationInfo(sysUser, password, getName());
            }
        }

        throw new IncorrectCredentialsException();*/
    }

}